﻿using System;
using System.Collections.Generic;
using EnvDTE;
using Microsoft.VisualStudio.TemplateWizard;
using Soat.SoPrism.TemplateWizards.Helpers;
using Soat.SoPrism.TemplateWizards.Properties;
using System.IO;

namespace Soat.SoPrism.TemplateWizards
{
    /// <summary>
    /// Cette classe représente un Wizard de base comportant l'ensemble des variables à utiliser pendant la génération de la solution
    /// </summary>
    public class CommonWizard : IWizard
    {
        public  Dictionary<string, string> ReplacementsDictionary { get; private set; }

        #region Consts

        /// <summary>
        /// Time pour le UnLock des fichiers par VS2010
        /// </summary>
        //const int MIN_TIME_FOR_PROJECT_TO_RELEASE_FILE_LOCK = 700;
        #endregion

        #region Original Folder property
        /// <summary>
        /// Répertoire d'origine du Projet 
        /// </summary>
        private string originalFolder = string.Empty;
        #endregion


        #region WizardParameterHelper Property

        /// <summary>
        /// Service d'aide pour la récupération des parametres du Wizard
        /// </summary>
        internal ParameterHelper WizardParameterHelper { get; private set; }

        #endregion

        #region WizardTemplateHelper Property
        
        /// <summary>
        /// Service d'aide pour la gestion des VSTemplates
        /// </summary>
        internal VSTemplateHelper WizardTemplateHelper { get; private set; } 

        #endregion

        #region WizardDTEHelper Property

        /// <summary>
        /// Service d'aide pour la gestion de l'environnement VS2010
        /// </summary>
        internal EnvDTEHelper WizardDTEHelper { get; private set; } 

        #endregion

        #region VSTemplateFilename Property

        /// <summary>
        /// Nom du fichier VSTemplate
        /// </summary>
        public string VSTemplateFilename { get; private set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Constructor par défaut
        /// </summary>
        public CommonWizard()
        {
            this.ReplacementsDictionary = new Dictionary<string, string>();
            this.WizardDTEHelper = new EnvDTEHelper();
            this.WizardTemplateHelper = new VSTemplateHelper();
        } 

        #endregion

        #region RunStarted Method

        /// <summary>
        /// Runs custom wizard logic at the beginning of a template wizard run.
        /// </summary>
        /// <param name="automationObject">The automation object being used by the template wizard.</param>
        /// <param name="replacementsDictionary">The list of standard parameters to be replaced.</param>
        /// <param name="runKind">A Microsoft.VisualStudio.TemplateWizard.WizardRunKind indicating the type of wizard run.</param>
        /// <param name="customParams">The custom parameters with which to perform parameter replacement in the project.</param>
        public virtual void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            this.VSTemplateFilename = Convert.ToString(customParams[0]);
            this.WizardParameterHelper = new ParameterHelper(automationObject);
            this.WizardParameterHelper.LoadParameters(replacementsDictionary);

            this.InitializeDictionary(replacementsDictionary);

            //this.ReplacementsDictionary.Clear();
            //foreach (var item in replacementsDictionary)
            //{
            //    this.ReplacementsDictionary.Add(item.Key, item.Value);
            //}
        }

        #endregion

        #region IWizard Members

        public virtual void BeforeOpeningFile(ProjectItem projectItem)
        {

        }

        public virtual void ProjectFinishedGenerating(Project project)
        {
            //try
            //{
            //    var projectFilename = project.Name;
            //    //var solutionFolder = project.
            //    var projectName = this.WizardParameterHelper.GetParameterValue("$projectName$");

            //    var newProjectPath = projectFilename;
            //    if (newProjectPath.StartsWith(projectName)) {
            //        newProjectPath = newProjectPath.Substring(projectName.Length + 1);
            //    }

            //    var currentFolder = new DirectoryInfo(Path.GetDirectoryName(project.FullName));
            //    var parentFolder = currentFolder.Parent;

            //    var newFolder = Path.Combine(parentFolder.FullName, newProjectPath);

            //    // Supprime le projet venant d'être ajouté
            //    (this.WizardParameterHelper.Globals).DTE.Solution.Remove(project);

            //    System.Threading.Thread.Sleep(Resources.MIN_TIME_FOR_PROJECT_TO_RELEASE_FILE_LOCK.ToInt32());

            //    // on déplace le répertoire
            //    currentFolder.MoveTo(newFolder);

            //    // Ajout à la solution du fichier Project renommé
            //    (this.WizardParameterHelper.Globals).DTE.Solution.AddFromFile(newFolder + "\\" + projectFilename + ".csproj", false);


            //    //var strNewProjectFilename = string.Format(Resources.MODULE_PROJECT_NAME, 
            //    //    this.WizardParameterHelper.GetParameterValue("$projectname$"), project.Name);

            //    //var projectFileInfo = new FileInfo(project.FullName);
            //    //var projectFolder = projectFileInfo.Directory;
            //    //this.originalFolder = projectFolder.FullName;
            //    //var newFolder = projectFolder.Parent.FullName + "\\" + string.Format(Resources.MODULE_PROJECT_FOLDER, this.WizardParameterHelper.GetParameterValue("$projectname$"), project.Name);

            //    //// Supprime le projet venant d'être ajouté
            //    //(this.WizardParameterHelper.Globals).DTE.Solution.Remove(project);

            //    //System.Threading.Thread.Sleep(MIN_TIME_FOR_PROJECT_TO_RELEASE_FILE_LOCK);

            //    //// Renome de fichier .csproj
            //    //projectFileInfo.MoveTo(projectFolder.FullName + "\\" + strNewProjectFilename);

            //    //// Déplace le contenu du répertoire du Projet crée
            //    //projectFolder.MoveTo(newFolder);

            //    //// Ajout à la solution du fichier Project renommé
            //    //(this.WizardParameterHelper.Globals).DTE.Solution.AddFromFile(newFolder + "\\" + strNewProjectFilename, false);
            //}
            //catch (Exception)
            //{
            //    // Nothing
            //}
        }

        public virtual void ProjectItemFinishedGenerating(ProjectItem projectItem)
        {

        }

        public virtual void RunFinished()
        {

        }

        public virtual bool ShouldAddProjectItem(string filePath)
        {
            return true;
        }

        #endregion

        #region virtual InitializeDictionary Method

        /// <summary>
        /// Cette méthode permet d'initialiser l'ensemble des variables en sessions dans Visual Studio
        /// </summary>
        /// <param name="replacementsDictionary">Parametres de remplacement</param>
        public virtual void InitializeDictionary(Dictionary<string, string> replacementsDictionary)
        {
            if (!replacementsDictionary.ContainsKey("$dataname$"))
            {
                replacementsDictionary.Add("$dataname$", replacementsDictionary["$projectname$"]);
            }
            else
            {
                replacementsDictionary["$dataname$"] = this.WizardParameterHelper.GetParameterValue("$dataname$");
            }

            // Effectue le remplacement dans les parametres a remplacer
            replacementsDictionary["$projectname$"] = this.WizardParameterHelper.GetParameterValue("$companyname$") + "." + this.WizardParameterHelper.GetParameterValue("$projectshortname$");
            replacementsDictionary["$safeprojectname$"] = this.WizardParameterHelper.GetParameterValue("$companyname$") + "." + this.WizardParameterHelper.GetParameterValue("$projectshortname$");
            if (!replacementsDictionary.ContainsKey("$companyname$"))
            {
                replacementsDictionary.Add("$companyname$", this.WizardParameterHelper.GetParameterValue("$companyname$"));
            }
            else
            {
                replacementsDictionary["$companyname$"] = this.WizardParameterHelper.GetParameterValue("$companyname$");
            }
            if (!replacementsDictionary.ContainsKey("$projectshortname$"))
            {
                replacementsDictionary.Add("$projectshortname$", this.WizardParameterHelper.GetParameterValue("$projectshortname$"));
            }
            else
            {
                replacementsDictionary["$projectshortname$"] = this.WizardParameterHelper.GetParameterValue("$projectshortname$");
            }

            for (int i = 1; i < 80; i++)
            {
                if (!replacementsDictionary.ContainsKey(string.Format("$guid{0}$", i)))
                {
                    replacementsDictionary.Add(string.Format("$guid{0}$", i), this.WizardParameterHelper.GetParameterValue(string.Format("$guid{0}$", i)));
                }
                else
                {
                    replacementsDictionary[string.Format("$guid{0}$", i)] = this.WizardParameterHelper.GetParameterValue(string.Format("$guid{0}$", i));
                }
            }

            // on modifie le répertoire dans lequel sera copié le projet pour limiter le nom de caractère dans le chemin
            var currentDirectory = new DirectoryInfo(replacementsDictionary["$destinationdirectory$"]);
            var parentDirectory = currentDirectory.Parent;
            var projectName = this.WizardParameterHelper.GetParameterValue("$projectName$");

            if (currentDirectory.Name.StartsWith(projectName)) {
                replacementsDictionary["$destinationdirectory$"] =
                    Path.Combine(parentDirectory.FullName, currentDirectory.Name.Substring(projectName.Length + 1));
            }
        } 

        #endregion

    }
}
